// esercizio_lista_doppiamente linkata.cpp : Defines the entry point for the console application.
//
/*
scrivere un programma che gestisca una lista di contatti ogni contatto conome,nome,azienda e numero tel ed è
ordinata per cognome la lista è una lista doppiamante linkata il programma prevede l' inseriento ordinato la
stampa e fornito il cognome la cancellazione

*/
#include "stdafx.h"
#include <iostream>
#define LEN 20
using namespace std;
typedef struct {
	char nome[LEN + 1];
	char cognome[LEN + 1];
	char azzienda[LEN + 1];
	int tel;

}CONTATTO;
typedef struct NODO {
	CONTATTO a;
	struct NODO*next;
	struct NODO*prec;
}NODO;
NODO*alloca_();
bool lista_vuota(NODO*n);
void leggi(NODO*n);
NODO*inserisci(NODO*n);
void stampa(NODO*n);
NODO*cancella(NODO*n);
void dealloca(NODO*n);
void menù();
int main()
{
	menù();

    return 0;
}
NODO*alloca_() {
	NODO*nuovo;
	nuovo = (NODO*)malloc(sizeof(NODO));
	nuovo->next = NULL;
	nuovo->prec = NULL;
	if (nuovo == NULL) {
		printf("erroe di allocazione memoria\n");
		system("pause");
		return 0;
	}
	return nuovo;
}
bool lista_vuota(NODO*n) {
	if (n == NULL) {
		return true;
	}
	else {
		return false;
	}
}

void leggi(NODO*n) {
	printf("inseire il cognome\n");
	scanf_s("%s", n->a.cognome, LEN + 1);
	printf("inseire il nome\n");
	scanf_s("%s", n->a.nome, LEN + 1);
	printf("inseire il  numero di telefono\n");
	scanf_s("%d", &n->a.tel, sizeof(int));
	printf("inseire il  nome della azzienda \n");
	scanf_s("%s", n->a.azzienda, LEN + 1);

}
NODO*inserisci(NODO*n) {
	NODO*nuovo = NULL;
	NODO*p;
	NODO*prec;
	if (lista_vuota(n) == true) {
		nuovo = alloca_();
		leggi(nuovo);
		return nuovo;
	}
	else {
		p = n;
		nuovo = alloca_();
		leggi(nuovo);
		while (p != NULL) {
			if (strcmp(p->a.cognome, nuovo->a.cognome) == 0 || strcmp(p->a.cognome, nuovo->a.cognome) == -1) {
				if (prec == NULL) {
					nuovo->next = p;
					p->prec = nuovo;
					return nuovo;
				}
				else {
					prec->next = nuovo;
					nuovo->prec = prec;
					nuovo->next = p;
					p->prec = nuovo;
					break;
				}
			}
			else {
				if (p->next == NULL) {
					p->next = nuovo;
					nuovo->prec = p;
					return n;
				}
			}

			p = p->next;
			prec = p;
		}
	}


}
void stampa(NODO*n) {
	NODO*p;
	int cont = 0;
	if (lista_vuota(n) == true) {
		printf("la lista è vuota\n");

	}
	else {

		p = n;
		while (p != NULL) {
		
				printf("nodo %d,nome %s cognome %s , azzienda %s telefono %d \n",cont, p->a.nome,p->a.cognome, p->a.azzienda,p->a.tel);
				cont++;
			p = p->next;

		}
	}
}
NODO*cancella(NODO*n) {
	NODO*p;
	NODO*prec;
	char cognome_[LEN + 1];
	NODO*q=NULL;
	bool trovato = false;
	if (lista_vuota(n) == true) {
		printf("la lsita è vuota\n");
		system("pause");
		return n;
	}
	else {
		printf("inseire il cognome\n");
		scanf_s("%s", cognome_, LEN + 1);
		p = n;
		while (p != NULL) {
			if (strcmp(cognome_, p->a.cognome) == 0) {
				trovato = true;
				if (prec == NULL) {
					if (p->next == NULL) {
						free(p);
						return NULL;
					}
					else {
						n = p->next;
						n->prec = NULL;
						free(p);
						return n;
					}
				}
				else {
					if (p->next == NULL) {
						prec->next = NULL;
						p->prec = NULL;
						free(p);
						return n;
					}
					else {
						prec->next = p->next;
						p->next = q;
						q->prec = prec;
						free(p);
						return n;
					}
				}
			}


			prec = p;
			p = p->next;
		}
		if (trovato == false) {
			printf("elemento non trovato\n");
			system("pause");
			return n;
		}

	}
}
void dealloca(NODO*n) {
	NODO*p;
	if (lista_vuota(n) == true) {
		printf("la lista è vuota\n");
		system("pause");
		
	}
	else {
		while (n != NULL) {
			p = n;
			n = p->next;
			p->prec = NULL;
			free(p);
			p = NULL;
		}
	}
	
}
void menù() {
	NODO*n;
	int scelta = 0;
	do {
		system("cls");
		printf("menù\n");
		printf("0.esci\n");
		printf("1.inserisci\n");
		printf("2.stampa\n");
		printf("3.cancella\n");
		scanf_s("%d", &scelta, sizeof(int));
		switch (scelta) {
		case 0:
			printf("arrivederci e lasciate la mancia\n");
			system("pause");
			break;
		case 1:
			n = inserisci(n);
			system("pause");
			break;
		case 2:
			stampa(n);
			system("pasue");
			break;
		case 3:
			n = cancella(n);
			system("pause");
			break;
		default:
			printf("valore non valido\n");
			system("pause");
			break;
		}

	} while (scelta!=0);

	dealloca(n);
}